package com.small.nacos.client.config.impl;

import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.common.utils.StringUtils;
import small.common.core.io.util.ConcurrentDiskUtil;
import small.common.core.io.util.FileIoUtil;
import small.common.core.system.util.JvmUtil;
import com.small.nacos.client.utils.SnapShotSwitch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;

/**
 * @Author zhoujin
 * @Date 2022/11/21 20:18
 */
public class LocalEncryptedDataKeyProcessor extends LocalConfigInfoProcessor {

    private final static Logger LOGGER = LoggerFactory.getLogger(LocalEncryptedDataKeyProcessor.class);

    /**
     * 读取故障转移文件秘钥
     *
     * @param serverName
     * @param dataId
     * @param group
     * @param tenant
     * @return
     */
    public static String getEncryptDataKeyFailover(String serverName, String dataId, String group, String tenant) {
        File localPath = getEncryptDataKeyFailoverFile(serverName, dataId, group, tenant);
        if (!localPath.exists() || !localPath.isFile()) {
            return null;
        }
        try {
            return FileIoUtil.readFile(localPath);
        } catch (IOException ioe) {
            LOGGER.error("[" + serverName + "] get failover error, " + localPath, ioe);
            return null;
        }
    }

    /**
     * 获取故障转移文件秘钥
     *
     * @param envName
     * @param dataId
     * @param group
     * @param tenant
     * @return
     */
    static File getEncryptDataKeyFailoverFile(String envName, String dataId, String group, String tenant) {
        File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
        tmp = new File(tmp, "encrypted-data-key");

        if (StringUtils.isBlank(tenant)) {
            tmp = new File(tmp, "failover");
        } else {
            tmp = new File(tmp, "failover-tenant");
            tmp = new File(tmp, tenant);
        }

        return new File(new File(tmp, group), dataId);
    }

    /**
     * 保存临时文件秘钥
     *
     * @param envName
     * @param dataId
     * @param group
     * @param tenant
     * @param encryptDataKey
     */
    public static void saveEncryptDataKeySnapshot(String envName, String dataId, String group, String tenant,
                                                  String encryptDataKey) {
        //判断是否需要保存快照
        if (!SnapShotSwitch.getIsSnapShot()) {
            return;
        }
        File file = getEncryptDataKeySnapshotFile(envName, dataId, group, tenant);
        try {
            if (null == encryptDataKey) {
                try {
                    com.alibaba.nacos.common.utils.IoUtils.delete(file);
                } catch (IOException ioe) {
                    LOGGER.error("[" + envName + "] delete snapshot error, " + file, ioe);
                }
            } else {
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    boolean isMdOk = parentFile.mkdirs();
                    if (!isMdOk) {
                        LOGGER.error("[{}] save snapshot error", envName);
                    }
                }
                if (JvmUtil.isMultiInstance()) {
                    ConcurrentDiskUtil.writeFileContent(file, encryptDataKey, Constants.ENCODE);
                } else {
                    com.alibaba.nacos.common.utils.IoUtils.writeStringToFile(file, encryptDataKey, Constants.ENCODE);
                }
            }
        } catch (IOException ioe) {
            LOGGER.error("[" + envName + "] save snapshot error, " + file, ioe);
        }
    }

    /**
     * 获取临时配置文件秘钥
     */
    public static String getEncryptDataKeySnapshot(String envName, String dataId, String group, String tenant) {
        if (!SnapShotSwitch.getIsSnapShot()) {
            return null;
        }
        File file = getEncryptDataKeySnapshotFile(envName, dataId, group, tenant);
        if (!file.exists() || !file.isFile()) {
            return null;
        }

        try {
            return FileIoUtil.readFile(file);
        } catch (IOException ioe) {
            LOGGER.error("[" + envName + "] get snapshot error, " + file, ioe);
            return null;
        }
    }

    /**
     * 获取临时配置秘钥文件
     *
     * @param envName
     * @param dataId
     * @param group
     * @param tenant
     * @return
     */
    private static File getEncryptDataKeySnapshotFile(String envName, String dataId, String group, String tenant) {
        File tmp = new File(LOCAL_SNAPSHOT_PATH, envName + "_nacos");
        tmp = new File(tmp, "encrypted-data-key");

        if (com.alibaba.nacos.api.utils.StringUtils.isBlank(tenant)) {
            tmp = new File(tmp, "snapshot");
        } else {
            tmp = new File(tmp, "snapshot-tenant");
            tmp = new File(tmp, tenant);
        }

        return new File(new File(tmp, group), dataId);
    }
}
